<template>
  <div class="ref" ref="elemRef">
    <p>ref、toRef、toRefs</p>
    <p>1. ref：{{ nameRef }} - {{ ageRef }}</p>
    <p>2. toRef: {{ state.name }} - {{ state.age }}, {{ ageStateRef }} - {{ nameStateRef }}</p>
    <p>3. toRefs: {{ name }} - {{ age }}</p>
    <p>4. elemRef: {{ elemRef }}</p>
    <p></p>
  </div>
</template>

<script lang="ts">
import { defineComponent, ref, reactive, toRef, toRefs, onMounted } from 'vue';

export default defineComponent({
  name: 'RefView',
  props: {
  },
  setup() {
    // 1. 返回一个响应式的、可更改的 ref 对象（值类型）
    const ageRef = ref(20) 
    const nameRef = ref('ionluo')

    setTimeout(() => {
      // 通过 .value 获取和修改值
      console.log('ageRef', ageRef.value) 
      ageRef.value = 25
      nameRef.value = 'ionluo111'
    }, 1500)

    // 2. 返回一个对象的响应式代理
    const state = reactive({
      name: 'ayou', // 这里可以是任意数据类型，包括 nameRef
      age: 100,
    })

    // 2. toRef 基于响应式对象上的一个属性，创建一个对应的 ref
    // 注意：toRef 并非产生响应式对象
    const ageStateRef = toRef(state, 'age')
    const nameStateRef = toRef(state, 'name')
    setTimeout(() => {
      state.age = 200
      state.name = 'ayou111'
      
      setTimeout(() => {
        ageStateRef.value = 300
        nameStateRef.value = 'ayou222'
      }, 1500)
    }, 1500)
    

    // 3. toRefs 将一个响应式对象转换为一个普通对象，这个普通对象的每个属性都是指向源对象相应属性的 ref。每个单独的 ref 都是使用 toRef() 创建的。
    const state2 = reactive({
      name: 'byou', // 这里可以是任意数据类型，包括 nameRef
      age: 0.1,
    })
    const state2AsRef = toRefs(state2)
    setTimeout(() => {
      state2.name = 'byou111'
      state2.age = 0.2
    }, 1500)

    // 4. 获取DOM结点
    const elemRef = ref(null)
    onMounted(() => {
      console.log('elemRef', elemRef.value)
    })

    // 5. setup不能直接返回reactive对象，只能是普通对象（本质上其应该也是一个组合函数）
    return {
      ageRef,
      nameRef,

      state,
      ageStateRef,
      nameStateRef,
      
      ...state2AsRef,

      elemRef,
    }

  }
});
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

</style>
